# coding:utf-8
'''
Created on 2015年6月25日

@author: Emrys
'''
import types
from functools import wraps


# class A:
#
#     def decorator1(self, func):
#         @wraps(func)
#         def wrapper(*args, **kwargs):
#             print('Decorator 1')
#             return func(*args, **kwargs)
#         return wrapper
#
#     @classmethod
#     def decorator2(cls, func):
#         @wraps(func)
#         def wrapper(*args, **kwargs):
#             print('Decorator 2')
#             return func(*args, **kwargs)
#         return wrapper
#
#
# # 这是property的一种用法
# class Person:
#     first_name = property()
#
#     @first_name.getter
#     def first_name(self):
#         print("first_name.getter")
#         return self._first_name
#
#     @first_name.setter
#     def first_name(self, value):
#         print("first_name.setter")
#         if not isinstance(value, str):
#             raise TypeError('Expected a string')
#         self._first_name = value


class Profiled:

    def __init__(self, func):
        wraps(func)(self)
        self.ncalls = 0

    def __call__(self, *args, **kwargs):
        self.ncalls += 1
        return self.__wrapped__(*args, **kwargs)

    def __get__(self, instance, cls):
        print("Progfiled __get__")
        if instance is None:
            return self
        else:
            return types.MethodType(self, instance)

    def outProfiled(self):
        print("HOHOH")


# class Spam:
#
#     @Profiled
#     def bar(self, x):
#         print(self, x)


@Profiled
def add(x, y):
    return x + y

if __name__ == "__main__":
    add(2, 3)
    #     add(4, 5)
    #     s = Spam()
    #     s.bar(1)
    #     s.bar(2)
    #     s.bar(3)
    add.outProfiled()
    print(type(add))
    print(add.ncalls)
